<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<script>


/* global document */
// Load the fonts
Highcharts.createElement('link', {
    href: 'https://fonts.googleapis.com/css?family=Dosis:400,600',
    rel: 'stylesheet',
    type: 'text/css'
}, null, document.getElementsByTagName('head')[0]);

Highcharts.theme = {
    colors: ['#7cb5ec', '#f7a35c', '#90ee7e', '#7798BF', '#aaeeee', '#ff0066',
        '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'],
    chart: {
        backgroundColor: null,
        style: {
            fontFamily: 'Dosis, sans-serif'
        }
    },
    title: {
        style: {
            fontSize: '16px',
            fontWeight: 'bold'
        }
    },
    tooltip: {
        borderWidth: 0,
        backgroundColor: 'rgba(219,219,216,0.8)',
        shadow: false
    },
    legend: {
        itemStyle: {
            fontWeight: 'bold',
            fontSize: '13px'
        }
    },
    xAxis: {
        gridLineWidth: 0,
        labels: {
            style: {
                fontSize: '12px'
            }
        }
    },
    yAxis: {
        labels: {
            style: {
                fontSize: '12px'
            }
        }
    },
    plotOptions: {
        candlestick: {
            lineColor: '#404048'
        }
    },


    // General
    background2: '#F0F0EA'

};

// Apply the theme
Highcharts.setOptions(Highcharts.theme);
</script>

<div id="jmetervers" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
<table id="platforms">
    <tr></tr>
</table>
<hr/>


<h3>Plugins Popularity</h3>
By the number of known users:
<div class="row">
    <div class="col-md-4" id="plugins">
        <ol><i class="fa fa-spin fa-spinner fa-2x"></i></ol>
    </div>
    <div class="col-md-8">
        <div id="tabHist">
            <div id="pluginhist" style="min-width: 310px; height: 300px; margin: 0 auto; margin-bottom: 5em"></div>
        </div>
        <div id="tabVers">
            <div id="pluginvers" style="min-width: 310px; height: 300px; margin: 0 auto"></div>
        </div>
    </div>
</div>

<script>
    function values(dict) {
        var values = [];
        var keys = Object.keys(dict).sort();
        for (var k = 0; k < keys.length; k++) {
            values.push(dict[keys[k]]);
        }
        return values;
    }

    function jmeter_graph(csv) {
        return {
            data: {
                csv: csv
            },
            title: {
                text: 'JMeter Versions'
            },
            subtitle: {
                text: 'Source: jmeter-plugins.org'
            },
            xAxis: {
                type: "datetime"
            },
            yAxis: {
                title: {
                    text: '% of known installations'
                },
                labels: {
                    formatter: function () {
                        return this.value + ' %';
                    }
                },
                endOnTick: false,
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '%'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            }
        };
    }

    function hist_series(data, divider) {
        var dates = Object.keys(data);
        dates.sort();

        var res = [];
        for (var n = 0; n < dates.length; n++) {
            var date = dates[n];
            var value = data[date];
            if (divider && divider[date]) {
                value = Math.round(1000.0 * value / divider[date]) / 10;
            }
            var pdate = Date.parse(date);
            if (pdate < new Date("2016-11-21")) {
                continue;
            }
            res.push([pdate, value]);
        }
        return res;
    }

    function plugin_hist_graph(id, plugin_data, pmgr_data) {
        return {
            plotOptions: {
                series: {
                    animation: false
                }
            },
            title: {
                text: 'Monthly Active Installations: ' + id
            },
            subtitle: {
                text: 'Source: jmeter-plugins.org'
            },
            xAxis: {
                type: "datetime",
                plotLines: [{
                    color: 'silver',
                    dashStyle: 'longdashdot',
                    value: new Date("2017-05-22"),
                    width: 1,
                    label: {
                        style: {
                            color: 'silver'
                        },
                        text: 'Changed installID format',
                        align: 'left'
                    }
                }]
            },
            yAxis: [
                {
                    tickAmount: 5,
                    opposite: true,
                    title: {
                        text: 'known installations'
                    },
                    endOnTick: false,
                    plotLines: [{
                        value: 0,
                        width: 1,
                        color: '#808080'
                    }]
                },
                {
                    gridLineWidth: 0,
                    title: {
                        text: '% of users',
                    },
                    labels: {
                        format: '{value} %',
                    },
                    endOnTick:false
                }
            ],
            legend: {
                borderWidth: 0,
                align: 'left',
                verticalAlign: 'top',
            },
            series: [
                {
                    name: id,
                    data: hist_series(plugin_data),
                    yAxis: 0,
                    zIndex: 1,
                    marker: {
                        radius: 0
                    }
                },
                {
                    name: "% of all users",
                    data: hist_series(plugin_data, pmgr_data),
                    lineWidth: 1,
                    //marker: 'none',
                    yAxis: 1,
                    marker: {
                        radius: 0
                    }
                }
            ]
        };
    }

    function plugin_vers_graph(id, data, repo_entry) {
        var series = [];
        var sum = values(data).reduce(function (a, b) {
            return a + b;
        }, 0);

        var keys = Object.keys(data);
        var repo_keys = Object.keys(repo_entry.versions);
        keys.sort();

        var other = 0;
        for (var n = 0; n < keys.length; n++) {
            var ver = keys[n];
            var val = Math.round(1000 * data[ver] / sum) / 10;
            if ($.inArray(ver, repo_keys) >= 0) {
                series.push(['v ' + ver, val]);
            } else {
                other += val;
            }
        }

        if (other) {
            series.push(['N/A', other]);
        }

        return {
            plotOptions: {
                series: {
                    animation: false
                }
            },
            chart: {
                type: 'column'
            },

            title: {
                text: 'Installations by Version: ' + id
            },
            subtitle: {
                text: 'Source: jmeter-plugins.org'
            },
            xAxis: {
                type: 'category'
            },
            yAxis: {
                title: {
                    text: '% of known installations'
                },
                labels: {
                    formatter: function () {
                        return this.value + ' %';
                    }
                },
                tickInterval: 5,
                endOnTick: false,
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '%'
            },
            legend: {
                enabled: false
            },
            series: [{
                name: 'Share',
                data: series
            }]
        };
    }

    function prepare_versions_csv(csv) {
        var csvMap = csvToArrayOfArray(csv);
        var lastLog = csvMap[csvMap.length - 2];                 // TODO: last line in file is empty
        var headers = csvMap[0];


        // Looking for the most actual versions of JMeter
        var newHeaders = ["date"];
        for (i = 1; i < lastLog.length; i++) {                   // zero index = date
            if (parseFloat(lastLog[i]) >= 1.0) {                 // LAST PERCENT
                newHeaders.push(headers[i])
            }
        }
        newHeaders.push("Other");

        var newCsv = [];
        newCsv.push(newHeaders);
        for (i = 1; i < csvMap.length - 1; i++) {                 // TODO: last line in file is empty
            var newValues = [];
            newValues.push(csvMap[i][0]);                         // push date
            var otherVal = 0.0;
            for (j = 1; j < headers.length; j++) {
                if (newHeaders.includes(headers[j])) {
                    newValues.push(csvMap[i][j]);
                } else {
                    if (!isEmpty(csvMap[i][j])) {
                        otherVal += parseFloat(csvMap[i][j]);
                    }
                }
            }
            newValues.push(otherVal);
            newCsv.push(newValues);
        }

        return arrayOfArrayToCsv(newCsv);
    };

    function isEmpty(str) {
        return (str.length === 0 || !str.trim());
    };

    function csvToArrayOfArray(csv) {
        rows = csv.split("\n");

        return rows.map(function (row) {
    	    return row.split(",");
        });
    };

    function arrayOfArrayToCsv(val) {
        var csv = "";
        for (i = 0; i < val.length; i++) {
            csv += val[i].join(",");
            csv += "\n";
        }
        return csv;
    };

    $(function () {
        $.getJSON('/dat/stats/platforms.json', function (data) {
            var tr = $('#platforms').find("tr");
            var refined = {};
            var sum = 0;
            for (var plat in data) {
                var val = data[plat];
                if (plat.indexOf("windows") === 0) {
                    plat = "windows";
                }

                if (!refined[plat]) {
                    refined[plat] = 0;
                }

                refined[plat] += val;
                sum += val;
            }

            for (plat in refined) {
                tr.append("<td>" + plat + ": " + (100 * refined[plat] / sum).toFixed(2) + "%</td>");
            }
        });

        $.get('/dat/stats/jmeter_versions_history.csv', function (csv) {
            $('#jmetervers').highcharts(jmeter_graph(prepare_versions_csv(csv)));
        });

        $.get('/repo/').success(function (repo_json) {
            var repo = {};
            for (var n = 0; n < repo_json.length; n++) {
                repo[repo_json[n]['id']] = repo_json[n];
            }

            $.get('/dat/stats/plugins_vers.json').success(function (vers_json) {
                $.get('/dat/stats/plugins_usage_history.json').success(function (json) {
                    var pmgr = {};
                    var list = [];
                    for (var k in json) {
                        if (k.startsWith('jmeter-')) continue;
                        if (!repo[k]) {
                            console.warn("No such entry in repo: " + k);
                            continue;
                        }

                        var values2 = values(json[k]);
                        var plugin = {
                            plugin: k,
                            label: repo[k]['name'],
                            data: json[k],
                            vers: vers_json[k],
                            last: values2[values2.length - 1]
                        };
                        list.push(plugin);
                        if (k == 'jpgc-plugins-manager') {
                            pmgr = plugin;
                        }
                    }

                    list.sort(function (a, b) {
                        var aa = a.last;
                        var bb = b.last;
                        if (aa < bb) return 1;
                        else if (aa > bb) return -1;
                        else return 0;
                    });

                    var cont = $("#plugins");
                    for (var n = 0; n < list.length; n++) {
                        var item = list[n];
                        var a = $("<a href='/?search=" + item.plugin + "'>" + item.label + "</a>");
                        a.data("plugin", item);
                        a.click(function (evt) {
                            evt.preventDefault();
                            var item = $(this).data("plugin");

                            $('#pluginhist').highcharts(plugin_hist_graph(item.plugin, item.data, pmgr.data));
                            $('#pluginvers').highcharts(plugin_vers_graph(item.plugin, item.vers, repo[item.plugin]));
                        });

                        var li = $("<li></li>");
                        li.append(a);
                        li.append("<span>: " + item.last + "</span>");
                        cont.find(".fa-spinner").remove();
                        cont.find("ol").append(li);
                    }

                    cont.find("ol li:first-child a").trigger("click");
                });
            });
        });
    });
</script>

